{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python385jvsc74a57bd073e03da126b73bfff3642ec5261d56fa25c444ea595de51041687efaa60dda41",
   "display_name": "Python 3.8.5 64-bit ('base': conda)"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import win32gui as gui\n",
    "import win32ui as ui\n",
    "import win32api as api\n",
    "import win32con\n",
    "import numpy as np\n",
    "import binascii,hashlib\n",
    "import pandas as pd\n",
    "\n",
    "from skimage.measure import compare_ssim\n",
    "\n",
    "# import sys\n",
    "# from PyQt5.QtWidgets import QApplication\n",
    "# from PyQt5.QtGui import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "199352 wow.ipynb - test - Visual Studio Code\n",
      "330096 魔兽世界\n",
      "262678 (12条消息) Python实现按键精灵(二)-找图找色_weixin_30419799的博客-CSDN博客 和另外 5 个页面 - 个人 - Microsoft​ Edge\n",
      "263080 07.mp4 - VLC media player\n",
      "3017254 test\n",
      "459658 NVIDIA GeForce Overlay\n",
      "263124 邮件\n",
      "197868 收件箱 - Qq ‎- 邮件\n",
      "132302 设置\n",
      "132326 设置\n",
      "722396 DesktopWindowXamlSource\n",
      "131506 Windows 输入体验\n",
      "329946 战网\n",
      "65926 Program Manager\n",
      "<>:8: SyntaxWarning: \"is not\" with a literal. Did you mean \"!=\"?\n",
      "<>:8: SyntaxWarning: \"is not\" with a literal. Did you mean \"!=\"?\n",
      "<ipython-input-27-006dfe3ffd21>:8: SyntaxWarning: \"is not\" with a literal. Did you mean \"!=\"?\n",
      "  if t is not \"\":\n"
     ]
    }
   ],
   "source": [
    "hwnd_title = dict() \n",
    "def get_all_hwnd(hwnd,mouse):\n",
    "    if gui.IsWindow(hwnd) and gui.IsWindowEnabled(hwnd) and gui.IsWindowVisible(hwnd):\n",
    "        hwnd_title.update({hwnd:gui.GetWindowText(hwnd)})\n",
    "gui.EnumWindows(get_all_hwnd, 0)\n",
    "\n",
    "for h,t in hwnd_title.items():\n",
    "    if t is not \"\":\n",
    "        print(h,t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "330096 魔兽世界\n"
     ]
    }
   ],
   "source": [
    "for h,t in hwnd_title.items():\n",
    "    if t == \"魔兽世界\":\n",
    "        hwnd = h\n",
    "        print(h,t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "0\n"
     ]
    }
   ],
   "source": [
    "hwnd = 0\n",
    "# 根据窗口句柄获取窗口的设备上下文DC（Divice Context）\n",
    "print(hwnd)\n",
    "hwndDC = gui.GetWindowDC(hwnd)\n",
    "# 根据窗口的DC获取mfcDC\n",
    "mfcDC = ui.CreateDCFromHandle(hwndDC)\n",
    "# mfcDC创建可兼容的DC\n",
    "saveDC = mfcDC.CreateCompatibleDC()\n",
    "# 创建bigmap准备保存图片\n",
    "saveBitMap = ui.CreateBitmap()\n",
    "# 获取监控器信息\n",
    "MoniterDev = api.EnumDisplayMonitors(None, None)\n",
    "x1=6\n",
    "y1=2\n",
    "w = 26\n",
    "h = 24\n",
    "\n",
    "# 为bitmap开辟空间\n",
    "saveBitMap.CreateCompatibleBitmap(mfcDC, w-x1, h-y1)\n",
    "# 高度saveDC，将截图保存到saveBitmap中\n",
    "saveDC.SelectObject(saveBitMap)\n",
    "# 截取从左上角（0，0）长宽为（w，h）的图片\n",
    "saveDC.BitBlt((0, 0), (w, h), mfcDC, (x1, y1), win32con.SRCCOPY)\n",
    "saveBitMap.SaveBitmapFile(saveDC, 'get.jpg')\n",
    "\n",
    "# signedIntsArray = saveBitMap.GetBitmapBits(True)\n",
    "# img = np.fromstring(signedIntsArray, dtype='uint8')\n",
    "# img.shape = (h-y1, w-x1, 4)\n",
    "\n",
    "gui.DeleteObject(saveBitMap.GetHandle())\n",
    "saveDC.DeleteDC()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[ 16,  19,  29,  98, 160,  37,  27,  25,  25,  25,  24,  22,  21,\n",
       "         19,  16,  15,  12,  11,   8,   8],\n",
       "       [ 20,  23,  35, 103, 170, 196,  29,  30,  29,  29,  30,  29,  27,\n",
       "         26,  22,  20,  17,  16,  13,  11],\n",
       "       [ 24,  26,  27,  52, 128, 170, 159,  38,  35,  34,  33,  33,  33,\n",
       "         32,  29,  27,  24,  20,  19,  16],\n",
       "       [ 26,  30,  33,  32,  53,  88, 169, 147,  36,  36,  37,  38,  39,\n",
       "         38,  36,  33,  32,  28,  23,  21],\n",
       "       [ 29,  33,  35,  38,  27,  48, 142, 175, 137,  41,  41,  44,  45,\n",
       "         43,  43,  40,  40,  35,  31,  29],\n",
       "       [ 33,  36,  37,  39,  40,  23,  66, 151, 181, 134,  45,  47,  48,\n",
       "         48,  50,  48,  46,  44,  38,  35],\n",
       "       [ 35,  38,  40,  41,  43,  25,  17, 110, 209, 212, 103,  49,  50,\n",
       "         51,  54,  55,  53,  50,  48,  40],\n",
       "       [ 37,  41,  43,  40,  44, 214, 158,  96,  80, 187, 241,  61, 108,\n",
       "         76,  55,  58,  58,  56,  53,  49],\n",
       "       [ 39,  46,  49,  40, 116, 217, 222, 151,  70, 184, 214, 246, 250,\n",
       "        201,  56,  61,  63,  62,  59,  55],\n",
       "       [ 40,  47,  47,  86,  96, 177, 227, 214, 115, 175, 237, 188, 124,\n",
       "        234, 176,  64,  64,  65,  63,  61],\n",
       "       [ 42,  46, 123, 212, 123, 106, 174, 103,  73, 173, 183, 134, 114,\n",
       "        137, 213, 110,  65,  67,  66,  66],\n",
       "       [ 39,  43,  54, 198, 209, 153,  88,  76, 117, 123, 128,  74, 161,\n",
       "        176, 111,  73,  68,  68,  68,  68],\n",
       "       [ 39,  35, 178, 110, 194, 165, 107,  49,  70,  69,  74, 157, 146,\n",
       "        157, 165,  74,  66,  70,  70,  70],\n",
       "       [ 38,  44, 189, 171,  89,  86,  89, 120,  53,  73, 164, 146, 118,\n",
       "         88,  87,  76,  66,  70,  70,  71],\n",
       "       [ 32,  36, 106, 157,  80,  60,  67,  93, 107, 105, 110, 106, 116,\n",
       "        134, 109, 149,  71,  69,  71,  70],\n",
       "       [ 28,  32,  36,  66, 103, 124,  73, 123, 152, 146, 110, 107, 103,\n",
       "         79, 110, 182, 133,  68,  70,  70],\n",
       "       [ 26,  30,  33,  37,  44,  75,  55, 123,  98, 102,  62,  32,  31,\n",
       "         72, 161, 174, 197,  90,  79,  68],\n",
       "       [ 23,  26,  31,  34,  35,  37, 100,  96,  73,  80,  84,  45,  68,\n",
       "        107, 128,  99, 189, 194, 190, 171],\n",
       "       [ 21,  25,  28,  34,  39,  40,  37,  45,  64,  82,  70, 125,  96,\n",
       "        108,  99, 125, 170, 203, 196, 203],\n",
       "       [ 24,  20,  28,  31,  57,  98,  45,  43,  45,  50,  79,  83, 114,\n",
       "         99, 130,  93,  99, 199, 147, 177],\n",
       "       [ 19,  19,  25,  31,  61, 109,  45,  45,  45,  45,  48,  83,  91,\n",
       "         99, 130,  83, 106, 110, 179, 114],\n",
       "       [ 15,  19,  24,  31,  35,  59,  40,  45,  45,  45,  43,  43,  76,\n",
       "         97, 124,  79, 100,  98,  90, 175]], dtype=uint8)"
      ]
     },
     "metadata": {},
     "execution_count": 62
    }
   ],
   "source": [
    "cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "22"
      ]
     },
     "metadata": {},
     "execution_count": 57
    }
   ],
   "source": [
    "len(img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 209,
   "metadata": {},
   "outputs": [],
   "source": [
    "x1=6\n",
    "y1=2\n",
    "w = 26\n",
    "h = 24\n",
    "\n",
    "# 为bitmap开辟空间\n",
    "saveBitMap.CreateCompatibleBitmap(mfcDC, w-x1, h-y1)\n",
    "# 高度saveDC，将截图保存到saveBitmap中\n",
    "saveDC.SelectObject(saveBitMap)\n",
    "# 截取从左上角（0，0）长宽为（w，h）的图片\n",
    "saveDC.BitBlt((0, 0), (w, h), mfcDC, (x1, y1), win32con.SRCCOPY)\n",
    "saveBitMap.SaveBitmapFile(saveDC, 'get.jpg')\n",
    "\n",
    "gui.DeleteObject(saveBitMap.GetHandle())\n",
    "saveDC.DeleteDC()\n",
    "\n",
    "del saveBitMap\n",
    "del hwndDC\n",
    "del mfcDC\n",
    "del saveDC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "img = cv2.imread(\"get.jpg\",cv2.IMREAD_COLOR)\n",
    "grayA = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_jpg = []\n",
    "list_jpg.append('./jpgDat/chu.jpg')\n",
    "list_jpg.append('./jpgDat/xu.jpg')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_gray = []\n",
    "for i in list_jpg:\n",
    "    imp= cv2.imread(i,cv2.IMREAD_COLOR)\n",
    "    gray = cv2.cvtColor(imp, cv2.COLOR_BGR2GRAY)\n",
    "    list_gray.append(gray)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "NameError",
     "evalue": "name 'grayA' is not defined",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-48-a049816e0b4c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mlist_gray\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m     \u001b[1;33m(\u001b[0m\u001b[0mscore\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdiff\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcompare_ssim\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgrayA\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfull\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m     \u001b[1;32mif\u001b[0m \u001b[0mscore\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0.5\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m         \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'index is: '\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlist_gray\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m         \u001b[1;32mbreak\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'grayA' is not defined"
     ]
    }
   ],
   "source": [
    "for i in list_gray:\n",
    "    (score, diff) = compare_ssim(grayA, i, full=True)\n",
    "    if score > 0.5:\n",
    "        print('index is: ',list_gray.index(i))\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "b'LAPTOP-876VG2JO16'"
      ]
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "source": [
    "binascii.a2b_hex(b'4c4150544f502d3837365647324a4f3136'.decode('utf-8'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "'a6499c80298c51895bcf5ef034cd690d'"
      ]
     },
     "metadata": {},
     "execution_count": 13
    }
   ],
   "source": [
    "n = hashlib.md5()\n",
    "s = \"LAPTOP-876VG2JO16\"\n",
    "n.update(s.encode('utf-8'))\n",
    "n.hexdigest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getImg(x, y, w, h):\n",
    "    # 魔兽世界有句柄保护，所以使用hwnd编码是无法进行句柄截图\n",
    "    hwnd = 0\n",
    "    # 根据窗口句柄获取窗口的设备上下文DC（Divice Context）\n",
    "    hwndDC = gui.GetWindowDC(hwnd)\n",
    "    # 根据窗口的DC获取mfcDC\n",
    "    mfcDC = ui.CreateDCFromHandle(hwndDC)\n",
    "    # mfcDC创建可兼容的DC\n",
    "    saveDC = mfcDC.CreateCompatibleDC()\n",
    "    # 创建bigmap准备保存图片\n",
    "    saveBitMap = ui.CreateBitmap()\n",
    "    # 获取监控器信息\n",
    "    MoniterDev = api.EnumDisplayMonitors(None, None)\n",
    "    # 屏幕截图位置，x、y为坐标点，w、h为宽度和高度\n",
    "\n",
    "    # 为bitmap开辟空间\n",
    "    saveBitMap.CreateCompatibleBitmap(mfcDC, w - x, h - y)\n",
    "    # 高度saveDC，将截图保存到saveBitmap中\n",
    "    saveDC.SelectObject(saveBitMap)\n",
    "    # 截取从左上角（0，0）长宽为（w，h）的图片\n",
    "    saveDC.BitBlt((0, 0), (w, h), mfcDC, (x, y), win32con.SRCCOPY)\n",
    "    # 对截取的saveBitMap进行数据格式转换，先转成bit类型，然后在进行numpy转换\n",
    "    signedIntsArray = saveBitMap.GetBitmapBits(True)\n",
    "    img = np.fromstring(signedIntsArray, dtype=\"uint8\")\n",
    "    # 根据像素格式进行斜度处理\n",
    "    img.shape = (h - y, w - x, 4)\n",
    "    # 析构数据，放置内存泄漏\n",
    "    gui.DeleteObject(saveBitMap.GetHandle())\n",
    "    saveDC.DeleteDC()\n",
    "    del saveBitMap\n",
    "    del hwndDC\n",
    "    del mfcDC\n",
    "    del saveDC\n",
    "    # 返回数据灰度图进行后续图片比较判定\n",
    "    return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0\n",
    "y = 0\n",
    "# 获取屏幕宽高\n",
    "w = api.GetSystemMetrics(win32con.SM_CXSCREEN)\n",
    "h = api.GetSystemMetrics(win32con.SM_CYSCREEN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stderr",
     "text": [
      "<ipython-input-25-fcf28a9f60e8>:24: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead\n  img = np.fromstring(signedIntsArray, dtype=\"uint8\")\n"
     ]
    }
   ],
   "source": [
    "img = getImg(x, y, w, h)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = []\n",
    "for i in range(11):\n",
    "    l.append(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "ValueError",
     "evalue": "cannot reshape array of size 11 into shape (5,2)",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-15-023bce33146f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ml\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ml\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m: cannot reshape array of size 11 into shape (5,2)"
     ]
    }
   ],
   "source": [
    "n = np.array(l).reshape(int(len(l)/2),2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   0  1\n",
       "0  0  1\n",
       "1  2  3\n",
       "2  4  5\n",
       "3  6  7\n",
       "4  8  9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>0</th>\n      <th>1</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>4</td>\n      <td>5</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>6</td>\n      <td>7</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>8</td>\n      <td>9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 13
    }
   ],
   "source": [
    "pd.DataFrame(n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "range(0, 10)"
      ]
     },
     "metadata": {},
     "execution_count": 1
    }
   ],
   "source": [
    "range(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n"
     ]
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ]
}